﻿using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Xml.Serialization;

namespace TianYu.Core.DataBase
{
    public partial class BaseModel : INotifyPropertyChanged
    {
        public BaseModel()
        {
        }

        public BaseModel(bool enabledPropertyChanged) => _enabledPropertyChanged = enabledPropertyChanged;

        private bool _enabledPropertyChanged = false;

        private ChangedPropertyCollection _changedPropertys;
        /// <summary>存储被修改过的属性</summary>
        [XmlIgnore, IgnoreDataMember]
        [Newtonsoft.Json.JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
        protected internal ChangedPropertyCollection ChangedPropertys
        {
            get
            {
                if (_changedPropertys == null) _changedPropertys = new ChangedPropertyCollection();
                return _changedPropertys;
            }
        }

        /// <summary>属性改变事件</summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>属性改变</summary>
        /// <param name="propertyName">属性名</param>
        protected virtual void OnPropertyChanged([CallerMemberName] String propertyName = null)
        {
            if (_enabledPropertyChanged == false || propertyName == null) return;
            ChangedPropertys[propertyName] = true;
            PropertyChanged?.Invoke(propertyName, new PropertyChangedEventArgs(propertyName));
        }

        public int PropertyChangedCount() => _changedPropertys == null ? 0 : _changedPropertys.Count;

        /// <summary>查检属性值是否改变</summary>
        /// <param name="propertyName">字段名</param>
        public bool IsChanged(string propertyName = null) => _enabledPropertyChanged && ChangedPropertys.Contains(propertyName);

        public virtual async Task<string> ToLogAsync(BaseModel oldModel, IServiceProvider serviceProvider)
        {
            if (_enabledPropertyChanged == false)
            {
                return string.Empty;
            }
            return await ToLogAsync(this, oldModel, serviceProvider);
        }

        public virtual async Task<string> ToLogAsync(string operationName, BaseModel oldModel, IServiceProvider serviceProvider)
        {
            var logContent = await ToLogAsync(oldModel, serviceProvider);
            if (logContent.IsNullOrWhiteSpace())
            {
                return string.Empty;
            }
            return $"{operationName}：{logContent}";
        }

        protected virtual async Task<string> ToLogAsync(BaseModel newBaseModel, BaseModel oldBaseModel, IServiceProvider serviceProvider)
        => await Task.FromResult(string.Empty);
    }
}